package com.zzyl.serve.service.impl.admin;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.List;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.bean.BeanUtils;
import com.zzyl.serve.domain.admin.*;
import com.zzyl.serve.dto.*;
import com.zzyl.serve.service.admin.*;
import com.zzyl.serve.util.CodeGenerator;
import com.zzyl.serve.vo.CheckInConfigVo;
import com.zzyl.serve.vo.CheckInDetailVo;
import com.zzyl.serve.vo.CheckInElderVo;
import com.zzyl.serve.vo.ElderFamilyVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zzyl.serve.mapper.admin.CheckInMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;

/**
 * 入住Service业务层处理
 *
 * @author 王崇琪
 * @date 2025-03-05
 */
@Service
public
class CheckInServiceImpl extends ServiceImpl<CheckInMapper, CheckIn> implements ICheckInService {
    @Autowired
    private CheckInMapper checkInMapper;

    /**
     * 查询入住
     *
     * @param id 入住主键
     * @return 入住
     */
    @Override
    public CheckIn selectCheckInById(Long id) {
        return getById(id);
    }

    /**
     * 查询入住列表
     *
     * @param checkIn 入住
     * @return 入住
     */
    @Override
    public List<CheckIn> selectCheckInList(CheckIn checkIn) {
        return checkInMapper.selectCheckInList(checkIn);
    }

    /**
     * 新增入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int insertCheckIn(CheckIn checkIn) {
        return save(checkIn) ? 1 : 0;
    }

    /**
     * 修改入住
     *
     * @param checkIn 入住
     * @return 结果
     */
    @Override
    public int updateCheckIn(CheckIn checkIn) {
        return updateById(checkIn) ? 1 : 0;
    }

    /**
     * 批量删除入住
     *
     * @param ids 需要删除的入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInByIds(Long[] ids) {
        return removeByIds(Arrays.asList(ids)) ? 1 : 0;
    }

    /**
     * 删除入住信息
     *
     * @param id 入住主键
     * @return 结果
     */
    @Override
    public int deleteCheckInById(Long id) {
        return removeById(id) ? 1 : 0;
    }


    @Autowired
    /*导入老人*/
    private IElderService elderService;
    @Autowired
    private IBedService bedService;
    @Autowired
    private IContractService contractService;
    @Autowired
    private ICheckInService checkInService;
    @Autowired
    private ICheckInConfigService checkInConfigService;

    @Override
    @Transactional
    public void apply(CheckInApplyDto dto) {
        // TODO 我们先通过dto来获得老人的信息,看老人是否存在并且是否是已经入住的
        CheckInElderDto checkInElderDto = dto.getCheckInElderDto();
        //获得身份证号
        String idCardNo = checkInElderDto.getIdCardNo();
        //通过身份证和状态去查看是否有老人,状态1是正在入住的
        LambdaQueryWrapper<Elder> lqw=new LambdaQueryWrapper<>();
        lqw.eq(Elder::getIdCardNo,idCardNo)
                .eq(Elder::getStatus,1);
        Elder elder = elderService.getOne(lqw);
        if(ObjectUtils.isNotEmpty(elder)){
            //不为空就说明当前有这个老人,而且这个老人还是在入住的,抛异常
            throw new BaseException("老人已入住");
        }
        // TODO 走到这就说明我们应该去更新床位状态了,先从dto里面获得床位的状态
        CheckInConfigDto checkInConfigDto = dto.getCheckInConfigDto();
        Long bedId = checkInConfigDto.getBedId();
        Bed bed = bedService.getById(bedId);
        bed.setBedStatus(1);
        bedService.updateById(bed);
        // TODO 我们判断老人是否是没有信息呢,还是说有信息,只是入住状态是别的
        //建一个老人的对象,可以复用上面的
        elder=new Elder();
        //属性拷贝
        BeanUtils.copyProperties(checkInElderDto,elder);
        //赋值其余的属性,状态,床位编号,床位id
        elder.setStatus(1);
        elder.setBedId(bedId);
        String bedNumber = bed.getBedNumber();
        elder.setBedNumber(bedNumber);
        LambdaQueryWrapper<Elder> lqw1=new LambdaQueryWrapper<>();
        lqw1.eq(Elder::getIdCardNo,idCardNo)
                .ne(Elder::getStatus,1);
        Elder elderDb = elderService.getOne(lqw1);
        //我们看老人是没有信息还是说入住状态是别的呢,看是否为空
        if(ObjectUtils.isNotEmpty(elderDb)){
            //不为空就说明它存在我们就给去修改数据

            elderService.updateById(elder);
        }
        //为空就去添加数据

        else{
            elderService.save(elder);
        }
        // TODO 去加签约的信息
        //使用第三方生成合同编号
        String contractNo="HT"+CodeGenerator.generateContractNumber();
        Contract contract=new Contract();
        CheckInContractDto checkInContractDto = dto.getCheckInContractDto();
        BeanUtils.copyProperties(checkInContractDto,contract);
        //设置属性
        Long id = elder.getId();
        contract.setContractNumber(contractNo);
        contract.setElderId(id);
        contract.setElderName(elder.getName());
        //还有开始日期,结束日期,状态等,从入住的时候开始算

        //判断状态,如果入住时间是在当前时间之后就是未生效,之前就是已经生效
        //签约时间小于等于当前时间合同生效
        LocalDateTime endDate = dto.getCheckInConfigDto().getEndDate();
        LocalDateTime startDate = dto.getCheckInConfigDto().getStartDate();
        Integer status = startDate.isBefore(LocalDateTime.now()) ? 0 : 1;
        contract.setEndDate(endDate);
        contract.setStartDate(startDate);
        contract.setStatus(status);
        contractService.save(contract);
        // TODO 先进行属性拷贝
        CheckIn checkIn=new CheckIn();
        BeanUtils.copyProperties(checkInConfigDto,checkIn);
        // 设置身份证号,老人姓名,老人id,床位,状态,备注(家属信息)
        checkIn.setElderId(id);
        checkIn.setElderName(elder.getName());
        checkIn.setBedNumber(elder.getBedNumber());
        checkIn.setIdCardNo(elder.getIdCardNo());
        checkIn.setStatus(0);

        checkIn.setRemark(JSON.toJSONString(dto.getElderFamilyDtoList()));
        checkInService.save(checkIn);
        //TODO 保存入住配置信息
        CheckInConfig config = new CheckInConfig();
        BeanUtils.copyProperties(dto.getCheckInConfigDto(), config);
        //只需要设置一个入住id即可
        config.setCheckInId(checkIn.getId());

        checkInConfigService.save(config);



    }
    //查看入住详情使用Mybatisplus去实现
    @Override
    public CheckInDetailVo findOne(Long id) {
        CheckInDetailVo checkInDetailVo=new CheckInDetailVo();
        //TODO 根据入住id查询到老人的信息
        Long elderId = getById(id).getElderId();
        Elder byId = elderService.getById(elderId);
        //属性拷贝
        CheckInElderVo checkInElderVo=new CheckInElderVo();
        BeanUtils.copyProperties(byId, checkInElderVo);
        //设置年龄,从byId里面拿到生日,然后跟当前时间进行运算
        String birthday = byId.getBirthday();
        //获得当前时间]
        LocalDate now = LocalDate.now();
        //将生日转换为LocalDate类型,也去使用工具类
        LocalDate birthdayDate = LocalDate.parse(birthday, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        Integer age= Period.between(birthdayDate, now).getYears();
        checkInElderVo.setAge(age);

        checkInDetailVo.setCheckInElderVo(checkInElderVo);
        //TODO 根据入住id找到对应的remark
        String remark = getById(id).getRemark();
        /*转化为JSON*/
        List<ElderFamilyVo> elderFamilyVoList = JSON.parseArray(remark, ElderFamilyVo.class);
        checkInDetailVo.setElderFamilyVoList(elderFamilyVoList);
        // TODO 根据入住id找到老人的id,根据老人id找到对应的合同信息
        // TODO 至于为什么这个不能跟老人一样通过入住的id查出来,因为老人表里面并没有合同id
        LambdaQueryWrapper<Contract> lqw=new LambdaQueryWrapper<Contract>();
        lqw.eq(Contract::getElderId,elderId);
        Contract contractOne = contractService.getOne(lqw);
        checkInDetailVo.setContract(contractOne);
        // TODO 补充入住配置信息 根据入住id
        LambdaQueryWrapper<CheckInConfig> lqw1=new LambdaQueryWrapper<>();
        lqw1.eq(CheckInConfig::getCheckInId,id);
        CheckInConfig checkInConfigOne = checkInConfigService.getOne(lqw1);
        CheckInConfigVo checkInConfigVo=new CheckInConfigVo();
            BeanUtils.copyProperties(checkInConfigOne,checkInConfigVo);
        //设置开始结束时间,床位,应该建一个对象的,很多地方都用到了入住对象
        String bedNumber = getById(id).getBedNumber();
        LocalDateTime endDate = getById(id).getEndDate();
        LocalDateTime startDate = getById(id).getStartDate();
        checkInConfigVo.setBedNumber(bedNumber);
        checkInConfigVo.setStartDate(startDate);
        checkInConfigVo.setEndDate(endDate);
        checkInDetailVo.setCheckInConfigVo(checkInConfigVo);
        return checkInDetailVo;


    }


   /* @Transactional
    @Override
    public void apply(CheckInApplyDto dto) {

        // 1.通过身份证号和状态查询老人
        LambdaQueryWrapper<Elder> elderQueryWrapper = new LambdaQueryWrapper<Elder>();
        elderQueryWrapper.eq(Elder::getIdCardNo, dto.getCheckInElderDto().getIdCardNo());
        elderQueryWrapper.eq(Elder::getStatus, 1);
        Elder elder = elderService.getOne(elderQueryWrapper);
        //同时满足这2个就说明已经入住
        if(ObjectUtils.isNotEmpty(elder)) {
            throw new BaseException("老人已入住");
        }
        //2.更新床位的状态我们把床位的状态改为已经入住
       // 通过入住配置去获得床位id
        CheckInConfigDto checkInConfigDto = dto.getCheckInConfigDto();
        Long bedId = checkInConfigDto.getBedId();
    //  使用Mybatisplus去获得床位对象
        Bed byId = bedService.getById(bedId);
      //  设置为入住申请中
        byId.setBedStatus(1);
      //  更新床位底层调用的是Mybatis的
        bedService.updateBed(byId);
        //3.更新或者保存老人状态
      //  属性拷贝
        CheckInElderDto checkInElderDto = dto.getCheckInElderDto();
        Elder elder1=new Elder();
        BeanUtils.copyProperties(checkInElderDto,elder1);
      //  我们的老人dto里面并没有床位的一些信息手动补充
        elder1.setBedNumber(byId.getBedNumber());
        elder1.setBedId(byId.getId());
        elder1.setStatus(1);
      //  查询老人信息
   //  加上身份证和状态
        LambdaQueryWrapper<Elder> lambdaQueryWrapper=new LambdaQueryWrapper<Elder>();
        lambdaQueryWrapper.eq(Elder::getIdCardNo,checkInElderDto.getIdCardNo()).ne(Elder::getStatus, 1);
        Elder one = elderService.getOne(lambdaQueryWrapper);
        if(ObjectUtils.isNotEmpty(one)){
       //     查到了老人就说明他在这里,我们就去更新信息

            elderService.updateElder(elder1);
        }
        else{
          //  看有没有查到老人就说明老人是第一次进来我们保存信息
            elderService.insertElder(elder1);
        }
        // 生成合同编号
        String contractNo = "HT" + CodeGenerator.generateContractNumber();
        Contract contract = new Contract();

        // 属性拷贝
        BeanUtils.copyProperties(dto.getCheckInContractDto(), contract);
        contract.setContractNumber(contractNo);
        contract.setElderId(elder1.getId());
        contract.setElderName(elder1.getName());
        // 状态、开始时间、结束时间
        // 签约时间小于等于当前时间，合同生效中
        LocalDateTime checkInStartTime = dto.getCheckInConfigDto().getStartDate();
        LocalDateTime checkInEndTime = dto.getCheckInConfigDto().getEndDate();
        Integer status = checkInStartTime.isBefore(LocalDateTime.now()) ? 0 : 1;
        contract.setStatus(status);
        contract.setStartDate(checkInStartTime);
        contract.setEndDate(checkInEndTime);
        contractMapper.insert(contract);
      //  新增入住办理
        CheckIn checkIn=new CheckIn();
        checkIn.setElderId(elder1.getId());
        checkIn.setElderName(elder1.getName());
        checkIn.setIdCardNo(elder1.getIdCardNo());
        checkIn.setNursingLevelName(dto.getCheckInConfigDto().getNursingLevelName());
        checkIn.setStartDate(dto.getCheckInConfigDto().getStartDate());
        checkIn.setEndDate(dto.getCheckInConfigDto().getEndDate());
        checkIn.setBedNumber(elder1.getBedNumber());
      //  我们的老人家属的信息都以JSON的形式写在了备注里面
        checkIn.setRemark(JSON.toJSONString(dto.getElderFamilyDtoList()));
        checkIn.setStatus(0);
        checkInMapper.insert(checkIn);






    }*/
}
